package com.example.demo.service.impl;

import com.example.demo.dao.ParserNcFileDao;
import com.example.demo.model.util.FtpDTO;
import com.example.demo.model.util.SitDTO;
import com.example.demo.service.ParserNcFileService;
import com.example.demo.util.FileUtil;
import com.example.demo.util.FtpUtil;
import com.example.demo.util.ParserNcFileUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service
public class ParserNcFileServiceImpl implements ParserNcFileService {

    @Resource
    private ParserNcFileDao parserNcFileDao;

    /**
     * 处理NC文件数据
     * @param xlength 6200
     * @param ylength 4200
     * @return
     */
    @Override
    public String getFromAllSite(int xlength,int ylength) throws Exception{
        Long st = System.currentTimeMillis();
        /** FTP下载文件 */
        FtpDTO f = new FtpDTO();
        f.setIpAddr("10.20.69.113");
        f.setUserName("satellite");
        f.setPwd("satellite");
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat formatH = new SimpleDateFormat("HH");
        Date date = new Date();
        String dir = format.format(date);
        String hh = formatH.format(date);
        f.setPath("/Output/RainMerge_BJT/"+dir);
        String path = "D:/data/rainfall_fusion/"+dir+"/";
        String fileName = "ACHN_MHR_"+dir+"_"+hh+"0000_01.nc";
        /** 下载ftp文件 */
        FtpUtil.startDown(f, path, fileName);
        String url = path+fileName;
        /** 文件存在就解析数据新增数据 */
//        File file = new File(url);
//        if (file.exists()) {
            short[][] vals = ParserNcFileUtil.getDataInfo(url, "rain_merge");
            if (null == vals) {
                throw new Exception("文件没有解析到数据.");
            }
            File fileNames = new File(url.trim());
            if (!fileNames.exists()) {
                System.out.println("解析文件不存在.");
                throw new Exception("解析文件不存在.");
            }
            String observeTime = dir + hh + "0000";
            System.out.println("时间为：" + observeTime);
            /** 查询出站点信息，处理成想要的key value格式的数据，经纬度拼接作为可以，站点作为value */
            List<SitDTO> sitRest = parserNcFileDao.getFromAllSite();
            HashMap sitMap = new HashMap();
            HashMap lonLatsMap = new HashMap();
            for (SitDTO sit : sitRest) {
                sitMap.put(sit.getLonLat(), sit.getStaCoNa());
                lonLatsMap.put(sit.getLonLat(), sit.getLonLats());
            }
            /** 查询该时间点，站点观测的降雨量 */
            List<SitDTO> sitRainRest = parserNcFileDao.getsitRainFall(observeTime);
            HashMap sitRainMap = new HashMap();
            for (SitDTO sit : sitRainRest) {
                sitRainMap.put(sit.getStaCoNa(), sit.getSitRainFAll());
            }
            /** 处理NC数据，获取对应站点的降雨量的值 */
            List<SitDTO> insSit = handleData(xlength, ylength, sitMap, sitRainMap, lonLatsMap, observeTime, vals);
            /** 数据保存 */
            boolean saveRest = saveData(insSit);
            if (!saveRest) {
                throw new Exception("未知错误");
            }
            /** 数据新增完 删掉NC文件 */
            boolean delerest = FileUtil.deleteFile(url);
            if (!delerest) {
                throw new Exception("文件删除失败.");
            }
//        }else {
//            System.out.println(f.getPath()+fileName+"服务器文件不存在。");
//        }
        Long en = System.currentTimeMillis();
        System.out.println("程序执行时间为：" + (en - st) + "ms");
        return "success";
    }

    /**
     * NC数据处理
     * @param xlength
     * @param ylength
     * @param sitMap
     * @param sitRainMap
     * @param lonLatsMap
     * @param observeTime
     * @param vals
     * @return
     */
    private List<SitDTO> handleData(int xlength,int ylength,
                                    HashMap sitMap, HashMap sitRainMap,
                                    HashMap lonLatsMap, String observeTime,
                                    short[][] vals){
        List<SitDTO> insSit = new ArrayList<>();
        for(int i=1220;i<ylength;i++){
            for(int j=7300;j<xlength;j++){
                StringBuffer lonLat = new StringBuffer();
                lonLat.append(j);
                lonLat.append(i);
                String sit = String.valueOf(sitMap.get(String.valueOf(lonLat)));
                String lonLats = String.valueOf(lonLatsMap.get(String.valueOf(lonLat)));
                if (null != sit && !"".equals(sit) && !"null".equals(sit)
                        && null != lonLats && !"".equals(lonLats) && !"null".equals(lonLats)){
                    String[] sitCoNa = sit.split(":");
                    /** 站点编号 */
                    String staCode = sitCoNa[0];
                    /** 站点名 */
                    String staName = sitCoNa[1];
                    SitDTO sitDTO = new SitDTO();
                    sitDTO.setStaCode(staCode);
                    sitDTO.setStaName(staName);
                    String[] lL = lonLats.split(":");
                    /** 经度 */
                    String lon = lL[0];
                    /** 纬度 */
                    String lat = lL[1];
                    sitDTO.setLon(Double.parseDouble(lon));
                    sitDTO.setLat(Double.parseDouble(lat));
                    sitDTO.setObserveTime(observeTime);
                    double rain=vals[i-1220][j-7300];
                    double rain1 = rain*10.0;
                    sitDTO.setNcRainFAll(rain1/100.0);
                    if(null != sitRainMap.get(sit)){
                        sitDTO.setSitRainFAll((double) sitRainMap.get(sit));
                    }else {
                        sitDTO.setSitRainFAll(0.0);
                    }
                    insSit.add(sitDTO);
                }
            }
        }
        return insSit;
    }

    /**
     * 数据保存
     * @param insSit
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public boolean saveData(List<SitDTO> insSit) throws Exception{
        if (null != insSit && insSit.size() > 0) {
            Long st2 = System.currentTimeMillis();
            int listSize1 = insSit.size();
            int toIndex1 = 150;
            for (int i = 0; i < insSit.size(); i += 150) {
                List newList = new ArrayList();
                if (i + toIndex1 > listSize1) {
                    newList = insSit.subList(i, listSize1);
                } else {
                    newList = insSit.subList(i, i + toIndex1);
                }
                /** 循环保存数据、分批 */
                int num = parserNcFileDao.insretSitRainFall(newList);
                if (num == 0 || num < newList.size()) {
                    throw new Exception("新增数据失败");
                }
            }
            Long en2 = System.currentTimeMillis();
            System.out.println("循环保存数据结束>>>>>>>>>>>>>>>>>>用时：" + (en2 - st2) + "ms");
            return true;
        }else {
            throw new Exception("没有数据,新增数据失败.");
        }
    }
}
